package arithmetic.thread.bolckqueen;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import lombok.extern.slf4j.Slf4j;
import utils.ValidUtils;

/**
 * 我的阻塞队列  synchronize wait notify写法
 *
 * @author jiangfeng on 2022/4/9
 */
public class MyBlockQueen<T> implements MyBlockQueenInterface<T> {

    public static Logger log = LoggerFactory.getLogger(MyBlockQueen.class);
    private final ArrayList<T> arrays;
    private final Integer maxLength;
    // 当前阻塞队列元素格式
    private AtomicInteger count = new AtomicInteger(0);


    public MyBlockQueen(int maxLength) {
        this.maxLength = maxLength;
        arrays = new ArrayList<T>(maxLength);
    }

    @Override
    // 关键点在于如何阻塞??
    public void put(T t) {
        synchronized (this) {
            // 最大数量需要阻塞
            while (count.get() == maxLength) {
                // 进入休眠
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            arrays.add(t);
            count.incrementAndGet();
            log.info("{},add: {}", Thread.currentThread().getName(), t);
            // 唤醒别的线程
            this.notify();

        }
    }

    @Override
    public T take() {

        synchronized (this) {
            // 没有元素需要阻塞
            while (count.get() == 0) {
                // 进入休眠
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            T remove = arrays.remove(count.getAndDecrement() - 1);
            log.info("{},take: {}", Thread.currentThread().getName(), remove);
            // 唤醒别的线程
            this.notify();
            return remove;
        }

    }


}
